#ifndef CVTHREAD_H
#define CVTHREAD_H

#include "stdafx.h"
#include <opencv2\opencv.hpp>  
#include "CalibrateWidget.h"
#include "CameraDS.h"

class CvThread : public QThread {
	Q_OBJECT
private:
	// phase 1 data <Coordination,Data>
	QList<QPair<QPair<int, int>, QList<int>>> phase1Data;
	// used in phase 1 to indicate current location
	int currentX = -1000;
	int currentY = -1000;

	// inter phase heat map matrix
	QList<QPair<QPair<int, int>, double>> heatmap;

	// phase 2 raw data, in pixel not degrees
	QList<QPair<float, float>> toCalibrate;
	QList<QPair<float, float>> calibrated;
	// phase 2 data offset
	double offsetX = 0;
	double offsetY = 0;
	// a sign set to true if is in phase 2
	bool isCalibrating = false;
	// phase 2 generating result
	void calibrate();

	// raw data from serial port
	QList<QList<int>> rawData;

	// calibrate phase 1 and 2
	void calibrateWithData(QList<int>);

	// width and height of the video/image
	int width = 0;
	int height = 0;
	// a sign if grid should be drawn
	bool shouldShowGrid = false;

	// the pixel that is highlighted/focused
	double px = -100;
	double py = -100;
	// the size of focus in pixel
	int scale = 30;

	// camera chosen
	int cameraId = 0;
	// STOP SIGN FOR QTHREAD
	bool shouldStop = false;

	// used in phase 1 and phase 2
	CalibrateWidget *calibrateWindow = NULL;

	// convert between cv and qt images
	QImage cv2QImage(IplImage *image);
	QImage mat2QImage(cv::Mat image);

	// drawing
	void drawGrid(IplImage *image);
	void drawLine(IplImage *image, int position, int length, bool xAxis);
	void drawShortLine(IplImage *image, int x, int y, int length, bool xAxis, CvScalar color = cvScalar(255, 255, 255));
	void drawRadarView(IplImage *pFrame, int x, int y, int scale);
	void drawCross(IplImage *image, int x, int y, CvScalar color = cvScalar(255, 255, 255),int length = 20);
	void drawText(IplImage *image, int x, int y, QString text, CvScalar color = cvScalar(255, 255, 255));

	// a mutex key
	HANDLE mutex;

	// used for sorting
	static bool compareIndexedData(QPair<QPair<int, int>, double> &data1, QPair<QPair<int, int>,double> &data2);

	// deprecated
	void rawToCalibrated(int x, int y);
	void setXY(int x, int y);
	void setDegree(double a, double b);
public:
	// phase 1 toggle and continuation
	bool calibratePhase1();
	// used in read phase 1 from file
	bool setPhase1Data(QList<QPair<QPair<int, int>, QList<int>>> &&newData);
	// phase 2 toggle
	bool toggleCalibrating();
	// phase 2 called in mouse clicks
	void commitCalibration(int before_x, int before_y);
	// used in read phase 2 from file
	void setPhase2Data(double offset1, double offset2);
	// set the size of focus
	void setScale(uint16_t my_scale);
	// enqueue data
	void enqueueRawData(QList<int>);
	// choose camera
	void setId(int id);
	// generate degree from pixel
	void degreeFromPixel(double x, double y, double *degree);
	// toggle display of grid
	bool toggleGrid();

	// QTHREAD
	void run();
	void stop();

	CvThread();
	~CvThread();
signals:
	// signals
	void gotNewData(QImage);
	void sendInfo(QString);
	void phase1(int, int);
};

#endif // !CVTHREAD_H

